#include<iostream>
#include<WinSock2.h>
#include <thread>
#include<string>
#pragma warning(disable:4996)
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
using namespace std;
char szBuffer[600] = { 0 };//接收缓冲区
char str[600] = { 0 };//发送缓冲区
char name[20];//保存用户昵称
char des[20];
struct Msg {
	char timeStamp[50];
	char msg[500];
	bool flag = false;
	bool chat = false;
}cmsg;//定义用户信息结构体
void sendMsg(SOCKET sock) {
	while (1) {
		cout << "发送内容：";
		cin >> cmsg.msg;
		if (strcmp(cmsg.msg, "CHAT") == 0) {
			cout << "请输入私聊对象昵称：";
			cin >> des;
			cout << "发送私聊内容：";
			cin >> cmsg.msg;
			cmsg.chat = true;
		}
		else if (strcmp(cmsg.msg, "Q") == 0) {
			cmsg.flag = false;
			return;
		}

		time_t now = time(NULL);
		strftime(cmsg.timeStamp, 50, "[%m-%d %X]", localtime(&now));

		strcpy(str, name);//可删，改为cin>>str
		strcat(str + 20, cmsg.timeStamp);
		strcat(str + 70, cmsg.msg);
		if (cmsg.chat) {
			strcat(str + 570, des);
			memset(des, 0, 20);
			cmsg.chat = false;
		}

		send(sock, str, 600 + sizeof(char), NULL);
		memset(str, 0, 600);
		memset(&cmsg.msg, 0, strlen(cmsg.msg));
		cmsg.flag = true;

	}
}
void recvMsg(SOCKET sock) {
	char curr[50];
	while (1) {
		memset(szBuffer, 0, 600);
		//接收服务器传回的数据
		int ret = recv(sock, szBuffer, 600, NULL);
		cmsg.flag = true;
		char temp_des[20] = { 0 };
		strcpy(temp_des, szBuffer + 570);
		//cout << "指定的目标：" << temp_des << endl;
		if (!temp_des[0] && ret > 500) {//无指定
			cout << "\n....................................." << endl;
			int i = 20;
			while (szBuffer[i]) { cout << szBuffer[i++]; }//解析时间
			cout << szBuffer;//解析发送人
			cout << ":";
			i = 70;
			while (szBuffer[i]) { cout << szBuffer[i++]; }
			cout << endl;
			cout << ".....................................\n" << endl << "发送内容：";
			memset(szBuffer, 0, 600);
			continue;
		}
		if (ret > 500 && temp_des[0] && strcmp(temp_des, name) != 0) {//有指定且非当前
			continue;
		}
		if (ret > 500 && temp_des[0] && strcmp(temp_des, name) == 0) {//有指定且是当前
			cout << "\n....................................." << endl;
			int i = 20;
			while (szBuffer[i]) { cout << szBuffer[i++]; }//解析时间
			cout << szBuffer;//解析发送人
			if (strcmp(temp_des, name) == 0) {
				cout << "(私聊)";
			}
			cout << ":";
			i = 70;
			while (szBuffer[i]) { cout << szBuffer[i++]; }
			cout << endl;
			cout << ".....................................\n" << endl << "发送内容：";
			memset(szBuffer, 0, 600);
		}
	}
}
int main() {
	cout <<
		" ____ _   _    _  _____   ____   _____  __" << endl <<
		"/ ___| | | |  / \\ | _ _| | __ ) / _ \\ \\/ /" << endl <<
		"| |  | |_| | / _ \\ | |   |  _ \\| | | \\  /" << endl <<
		"| |__| ___ |/ ___ \\| |   | |_) | |_| /  \\" << endl <<
		"\\___ | | |_/_/   \\_\\_|   |____/ \\___/_/\\_\\" << endl <<
		"\n\n.............................................................................." <<
		endl;
	cout << "|  欢迎来到聊天小盒子！\n|  默认进入模式为[群聊模式]，想要进入[私聊模式]请输入\'CHAT\'，结束聊天请输入\'Q\'" << endl;
	cout << "|  您的昵称是：";
	cin >> name;
	cout << ".............................................................................." << endl;
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);//希望用户使用2.2版本的Socket
	SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);


	struct sockaddr_in sockAddr;//sockaddr_in用作定义，socketaddr用作函数参数
	memset(&sockAddr, 0, sizeof(sockAddr));  //将结构体清零
	sockAddr.sin_family = PF_INET;//TCP
	sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");//指定服务器IP
	sockAddr.sin_port = htons(1234);//指定服务器端口
	connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));//连接到服务器
	cmsg.flag = true;
	int res = send(sock, name, 20 + sizeof(char), NULL);
	if (res) {//把用户名发过去
		Sleep(500);
		thread t1(sendMsg, sock);
		thread t2(recvMsg, sock);
		t1.detach();
		t2.detach();
	}
	while (cmsg.flag) {}
	closesocket(sock);
	WSACleanup();
	return 0;
}
